package com.samoiloff.framework.commands {
	import flash.events.Event;

	/**
	 * @author Samoiloff
	 */
	public class CommandsQueue extends Command {
		
		protected var _arr		: Array;
		
		/*
		 * delay
		 */

		public function CommandsQueue() {
			_arr = [];
		}

		override public function destroy():void {
			removeAllActions();
			
			super.destroy();
		}
		
		private function removeAllActions():void {
			var action:Command = getItemAt(0);

			if (action) {
				removeListeners(action);
			}
			
			for (var i : int = 0; i < length; i++) {
				action = getItemAt(i);
				action.destroy();
			}
			_arr = null;
		}

		
		public function addAction(action : Command) : void {
			_arr.push(action);
		}
		
		public function removeAction(action:Command):void {
			removeListeners(action);
			
			var index: int = _arr.indexOf(action);
			_arr.splice(index, 1);

			action.destroy();
		}

		override public function start() : void {
			if (!_started) {
				_started = false;
				dispatchEvent(new CommandEvent(CommandEvent.ACTIONS_COMPLETE, this));
				proceed();
			}
		}
		
		protected function addListeners(action : Command) : void {
			action.addEventListener(CommandEvent.ACTION_START, onActionStart, false, -1);
			action.addEventListener(CommandEvent.ACTION_COMPLETE, onActionComplete, false, -1);
			action.addEventListener(CommandEvent.ACTION_CANCEL, onActionCancel, false, -1);
		}
		
		protected function removeListeners(action : Command):void {
			action.removeEventListener(CommandEvent.ACTION_START, onActionStart);
			action.removeEventListener(CommandEvent.ACTION_COMPLETE, onActionComplete);
			action.removeEventListener(CommandEvent.ACTION_CANCEL, onActionCancel);
		}

		protected function proceed():void {
			if (length > 0) {
				next();
			} else {
				finish();
			}
		}

		private function next():void {
			var action : Command = getItemAt(0);
			addListeners(action);
			action.start();
		}
		
		
		override protected function finish() : void {

		}
		
		
		private function onActionCancel(e : Event) : void {
			removeAllActions();
			_arr = [];
			dispatchEvent(new CommandEvent(CommandEvent.ACTIONS_CANCEL, this));
			proceed();
		}

		protected function onActionStart(event:CommandEvent):void {
			dispatchEvent(event);
		}
		
		protected function onActionComplete(event : CommandEvent) : void {
			dispatchEvent(event);
			if (_arr) { // not destroyed
				removeAction(getItemAt(0));
				proceed();
			}
		}
		
		public function get length() : int {
			return _arr.length;
		}
		
		public function getItemAt(i : int) : Command {
			return _arr[i] as Command;
		}
		
		
	}
}
